﻿using LiteBlog.Common.Entities;
using LiteBlog.Common.Enums;
using LiteBlog.Repositories.Common;
using LiteBlog.Repositories.Contracts;
using LiteBlog.Repositories.Framework;
using LiteBlog.Repositories.Helpers;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Web;
using System.Xml.Linq;

namespace LiteBlog.Repositories
{
    public class PostCommentRepository : DataAccess, IRepository
    {
        public PostCommentRepository(IDataContext context, IXmlHelper xmlHelper) : base(context, xmlHelper)
        {
            
        }

        internal List<Comment> Get(XElement postElem, string fileId)
        {
            var comments = new List<Comment>();
            XElement commentsElem = postElem.Element("Comments");
            if (commentsElem != null)
            {
                foreach (XElement commentElem in commentsElem.Elements("Comment"))
                {
                    Comment comment = new Comment();
                    comment.FileID = fileId;
                    comment.ID = commentElem.Attribute("ID").Value;
                    comment.Name = commentElem.Attribute("Name").Value;
                    comment.Text = HttpUtility.HtmlDecode(_xmlHelper.GetInnerXml(commentElem));
                    comment.Url = commentElem.Attribute("Url").Value;
                    comment.Time = DateTime.ParseExact(
                        commentElem.Attribute("Time").Value,
                        Constants.DateTimeFormat,
                        CultureInfo.InvariantCulture);
                    comment.Ip = commentElem.Attribute("Ip").Value;
                    if (commentElem.Attribute("IsAuthor") != null)
                    {
                        comment.IsAuthor = bool.Parse(commentElem.Attribute("IsAuthor").Value);
                    }

                    comments.Add(comment);
                }
            }
            return comments;
        }

        internal void Create(Comment comment)
        {
            _path = _context.GetPath(DataStoreType.Post, comment.FileID);
            var root = _xmlHelper.Load(_path);
            var commentsElem = root.Element("Comments");
            if (commentsElem != null)
            {
                XElement commentElem = new XElement(
                    "Comment",
                    new XAttribute("ID", comment.ID),
                    new XAttribute("Name", comment.Name),
                    new XAttribute("Url", comment.Url ?? string.Empty),
                    new XAttribute(
                        "Time", comment.Time.ToString(Constants.DateTimeFormat, CultureInfo.InvariantCulture)),
                    new XAttribute("Ip", comment.Ip),
                    new XAttribute("IsAuthor", comment.IsAuthor));

                commentElem.Value = comment.Text;
                commentsElem.AddFirst(commentElem);
            }

            int count = int.Parse(root.Attribute("Comments").Value);
            root.SetAttributeValue("Comments", count++);
            _xmlHelper.Save(root, _path);
        }

        internal void Update(Comment comment)
        {
            _path = _context.GetPath(DataStoreType.Post, comment.FileID);
            var root = _xmlHelper.Load(_path);
            var commentElem =   root.Element("Comments")
                                    .Elements("Comment")
                                    .Single(elem => (string)elem.Attribute("ID") == comment.ID);
            commentElem.SetAttributeValue("Name", comment.Name);
            commentElem.SetAttributeValue("Url", comment.Url ?? string.Empty);
            commentElem.SetAttributeValue("IsAuthor", comment.IsAuthor);
            commentElem.Value = comment.Text;
            _xmlHelper.Save(root, _path);
        }

        internal void Delete(string id, string fileId)
        {
            _path = _context.GetPath(DataStoreType.Post, fileId);
            var root = _xmlHelper.Load(_path);

            var commentElem = root.Element("Comments")
                                  .Elements("Comment")
                                  .SingleOrDefault(elem => (string)elem.Attribute("ID") == id);

            if (commentElem != null)
                commentElem.Remove();

            int count = int.Parse(root.Attribute("Comments").Value);
            root.SetAttributeValue("Comments", --count);
            _xmlHelper.Save(root, _path);
        }
    }
}
